package com.easylinkin.linkappapi.childinspection.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.easylinkin.linkappapi.childinspection.entity.*;
import com.easylinkin.linkappapi.childinspection.mapper.*;
import com.easylinkin.linkappapi.childinspection.service.InspectionPointService;
import com.easylinkin.linkappapi.childinspection.vo.BaseVo;
import com.easylinkin.linkappapi.childinspection.vo.InspectionPointVo;
import com.easylinkin.linkappapi.childinspection.vo.RelationVo;
import com.easylinkin.linkappapi.common.model.RequestModel;
import com.easylinkin.linkappapi.security.context.LinkappUserContextProducer;
import com.easylinkin.linkappapi.security.entity.LinkappUser;
import com.easylinkin.linkappapi.security.mapper.LinkappUserMapper;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.BeanUtils;
import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.Assert;

import javax.annotation.Resource;
import java.text.SimpleDateFormat;
import java.util.*;
import java.util.regex.Matcher;
import java.util.regex.Pattern;


/**
 * @author linWenLe
 * @Date: 2024/3/27
 * @Description:
 */
@Slf4j
@Service("inspectionPointService")
public class InspectionPointServiceImpl extends ServiceImpl<InspectionPointMapper, InspectionPointEntity> implements InspectionPointService {

    @Resource
    LinkappUserContextProducer linkappUserContextProducer;

    @Resource
    private InspectionRecordMapper inspectionRecordMapper;

    @Resource
    private InspectionPointMapper inspectionPointMapper;

    @Resource
    private InspectionQrCodeMapper inspectionQrCodeMapper;

    @Resource
    private RectificationRecordMapper rectificationRecordMapper;

    @Resource
    private InspectionMapper inspectionMapper;

    @Resource
    private LinkappUserMapper linkappUserMapper;

    public static final String INSPECTION_POINT_CODE = "XJDBH";

    @Scheduled(cron = "0 5 0 * * ?")//  0 0/5 * * * ?
    public void schedule() {
        try {
            log.info("start execute 巡检定时任务................ 开始");
            createTask();
            log.info("start execute 巡检定时任务................ 结束");
        }catch (Exception e){
            log.error("start execute 巡检定时任务................ 异常", e);
        }
    }

    public void createTask() {
        List<InspectionPointEntity> pointList = inspectionPointMapper.selectList(Wrappers.<InspectionPointEntity>lambdaQuery().eq(InspectionPointEntity::getInspectionPointStatus, 1));
        InspectionTaskEntity entity = new InspectionTaskEntity();
        String uuid = UUID.randomUUID().toString();
        entity.setId(uuid);
        String taskName = new SimpleDateFormat("yyyy年MM月dd日").format(new Date()) + "新增巡检任务";
        entity.setInspectionName(taskName);
        Calendar calendar = Calendar.getInstance();
        calendar.set(Calendar.HOUR_OF_DAY, 0);
        calendar.set(Calendar.MINUTE, 0);
        calendar.set(Calendar.SECOND, 0);
        calendar.set(Calendar.MILLISECOND, 0);
        entity.setStartTime(calendar.getTime());
        calendar.add(Calendar.DATE, 1);//加一天
        calendar.add(Calendar.SECOND, -1);//减一秒
        entity.setEndTime(calendar.getTime());
        entity.setCreateTime(new Date());
        entity.setInspectionPoint(pointList.size());
        entity.setSchedule(0d);
//        entity.setPersonId(getUserList());//定时任务无法获取租户ID，配置固定需修改
        entity.setPersonName("全体巡检员");
        inspectionMapper.insert(entity);
        for (InspectionPointEntity point : pointList) {
            inspectionMapper.insertTaskAndPoint(uuid, point.getId());
        }
    }

    public String getUserList(){
        QueryWrapper<LinkappUser> userQueryWrapper = new QueryWrapper<>();
        userQueryWrapper.eq("tenant_id", "5a920f536428050edddcce5212f36a97");
        List<LinkappUser> linkappUsers = linkappUserMapper.selectList(userQueryWrapper);
        StringBuilder sb = new StringBuilder();
        for (LinkappUser user : linkappUsers) {
            sb.append(user.getId()).append(",");
        }
        sb.deleteCharAt(sb.length() - 1);
        return sb.toString();
    }

    public static void main(String[] args) {
        Calendar calendar = Calendar.getInstance();
        calendar.set(Calendar.HOUR_OF_DAY, 0);
        calendar.set(Calendar.MINUTE, 0);
        calendar.set(Calendar.SECOND, 0);
        calendar.set(Calendar.MILLISECOND, 0);
        String format1 = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(calendar.getTime());
        System.out.println(format1);
        calendar.add(Calendar.DATE, 1);
        String format2 = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(calendar.getTime());
        System.out.println(format2);
    }

    @Override
    public IPage<InspectionPointEntity> getInspectionPointList(RequestModel<InspectionPointVo> restPage) {
        Page page = restPage.getPage();
        return inspectionPointMapper.getInspectionPointList(page, restPage.getCustomQueryParams());
    }

    @Override
    public String createPointCode() {
        String inspectionPointCode = inspectionPointMapper.selectMaxCode();
        if (inspectionPointCode == null){
            return INSPECTION_POINT_CODE + "0001";
        }
        Pattern pattern = Pattern.compile("\\d+(\\.\\d+)?");
        Matcher matcher = pattern.matcher(inspectionPointCode);
        int number = 0;
        while (matcher.find()) {
            number = Integer.parseInt(matcher.group()) + 1;
        }
        int length = 4; // 指定字符串的长度
        return INSPECTION_POINT_CODE + String.format("%0" + length + "d", number);
    }


    @Override
    @Transactional
    public void insertPoint(InspectionPointVo entityVo) {
        Assert.notNull(entityVo.getInspectionPointCode(), "巡检点编号不能为空");
        LambdaQueryWrapper<InspectionPointEntity> floorWrapper = Wrappers.lambdaQuery();
        List<InspectionPointEntity> codeList = inspectionPointMapper.selectList(floorWrapper.eq(InspectionPointEntity::getInspectionPointCode, entityVo.getInspectionPointCode()));
        if (codeList.size() > 0){
            throw new RuntimeException("巡检点编号已存在");
        }
        Assert.notNull(entityVo.getInspectionPointName(), "巡检点名称不能为空");
        List<InspectionPointEntity> nameList = inspectionPointMapper.selectList(floorWrapper.eq(InspectionPointEntity::getInspectionPointName, entityVo.getInspectionPointName()));
        if (nameList.size() > 0){
            throw new RuntimeException("巡检点名称已存在");
        }
        //判断二维码是否已被使用
        InspectionQrCodeEntity codeEntity = inspectionQrCodeMapper.selectById(entityVo.getQrCodeId());
        if (codeEntity != null){
            Assert.isTrue(codeEntity.getStatus() == 0, "二维码已被使用");
        }
        String tenantId = linkappUserContextProducer.getNotNullCurrent().getTenantId();
        InspectionPointEntity entity = new InspectionPointEntity();
        BeanUtils.copyProperties(entityVo,entity);
        String uuid = UUID.randomUUID().toString();
        entity.setId(uuid);
        entity.setCreateTime(new Date());
        entity.setCreator(tenantId);
        entity.setTenantId(tenantId);
        if (entityVo.getEffect() == 0) {//立即生效
            LambdaQueryWrapper<InspectionPointEntity> pointWrapper = Wrappers.lambdaQuery();
            InspectionPointEntity pointEntity = inspectionPointMapper.selectOne(pointWrapper.eq(InspectionPointEntity::getInspectionPointCode, entityVo.getInspectionPointCode()));
            //添加巡检任务
            inspectionMapper.insertTaskAndPoint(uuid, pointEntity.getId());
        }
        inspectionPointMapper.insert(entity);

        //新增二维码使用记录
        if (codeEntity != null) {
            RelationVo vo = new RelationVo(entityVo.getQrCodeId(), codeEntity.getCode(), entityVo.getId(), entityVo.getInspectionPointName(), 1);
            inspectionQrCodeMapper.insertQrCodeRecord(vo);
            //二维码关联巡检点
            inspectionQrCodeMapper.updateRelation(vo);
        }
    }

    @Override
    @Transactional
    public void updatePoint(InspectionPointEntity entity) {
        InspectionPointEntity pointEntity = inspectionPointMapper.selectById(entity.getId());
        if (!Objects.equals(pointEntity.getQrCodeId(), entity.getQrCodeId())){//修改二维码
            //判断二维码是否已被使用
            InspectionQrCodeEntity codeEntity = inspectionQrCodeMapper.selectById(entity.getQrCodeId());
            if (codeEntity.getStatus() != 0){
                Assert.isTrue(Objects.equals(codeEntity.getInspectionPointId(), entity.getId()), "二维码已被使用");
            }else {
                RelationVo vo = new RelationVo(entity.getQrCodeId(),codeEntity.getCode(), entity.getId(), entity.getInspectionPointName(), 1);
                //根据巡检点id修改结束时间
                inspectionQrCodeMapper.updateQrCodeRecordByPointId(vo.getInspectionPointId());
                //修改原二维码记录
                inspectionQrCodeMapper.cleanRelation(vo);
                //新增二维码使用记录
                inspectionQrCodeMapper.insertQrCodeRecord(vo);
                //二维码关联巡检点
                inspectionQrCodeMapper.updateRelation(vo);
            }
        }
        entity.setModifyTime(new Date());
        entity.setModifier(linkappUserContextProducer.getNotNullCurrent().getTenantId());
        inspectionPointMapper.updateById(entity);
    }

    @Override
    public void deletePoint(String id) {
        inspectionPointMapper.deleteById(id);
    }

    @Override
    public InspectionPointEntity pointInfo(String id) {
        InspectionPointEntity entity = inspectionPointMapper.selectById(id);
        Assert.notNull(entity, "巡检点不存在");
        if (entity.getQrCodeId() != null) {
            InspectionQrCodeEntity qrCodeEntity = inspectionQrCodeMapper.selectById(entity.getQrCodeId());
            entity.setQrCodeImage(qrCodeEntity.getImageUrl());
            entity.setQrCodeStatus(qrCodeEntity.getStatus());
        }
        LambdaQueryWrapper<InspectionRecordEntity> wrapper = Wrappers.lambdaQuery();
        wrapper.eq(InspectionRecordEntity::getPointId, id).orderByDesc(InspectionRecordEntity::getCreateTime);
        List<InspectionRecordEntity> recordList = inspectionRecordMapper.selectList(wrapper);
        entity.setInspectionCount(recordList.size());
        //查询二维码状态
        InspectionQrCodeEntity codeEntity = inspectionQrCodeMapper.selectById(entity.getQrCodeId());
        if (codeEntity != null){
            entity.setQrCodeStatus(codeEntity.getStatus());
        }
        return entity;
    }

    @Override
    public IPage<InspectionRecordEntity> pointRecordInfo(RequestModel<BaseVo> restPage) {
        Page page = restPage.getPage();
        BaseVo model = restPage.getCustomQueryParams();
        return inspectionRecordMapper.selectPointRecordInfoList(page, model);
    }

    @Override
    public IPage<InspectionRecordEntity> todayRecordInfo(RequestModel<BaseVo> restPage) {
        Page page = restPage.getPage();
        BaseVo model = restPage.getCustomQueryParams();
        return inspectionRecordMapper.selectTodayRecordInfo(page, model);
    }

    @Override
    public InspectionRecordEntity rectificationInfo(String recordId) {
        InspectionRecordEntity recordEntity = inspectionRecordMapper.selectById(recordId);
        LambdaQueryWrapper<RectificationRecordEntity> wrapper = Wrappers.lambdaQuery();
        List<RectificationRecordEntity> rectificationRecord = rectificationRecordMapper.selectList(wrapper.eq(RectificationRecordEntity::getRecordId, recordId));
        if (rectificationRecord.size() > 0){
            recordEntity.setList(rectificationRecord);
        }
        return recordEntity;
    }
}
